package org.blogwu.learn.threadLearn.使用unsafe实现原子性.测试获取偏移量;

import org.openjdk.jol.info.ClassLayout;
import org.openjdk.jol.info.GraphLayout;
import sun.misc.Unsafe;

import java.lang.reflect.Field;

public class Main {
    int cc = 0;
    byte aa;
    static Unsafe unsafe = null;
    int dd = 0;
    static volatile int a = 0;
    static long valueOffset;

    static {
        try {
            Field f = Unsafe.class.getDeclaredField("theUnsafe"); //获得名为 theUnsafe 的属性 即使为私有 同样获得
            f.setAccessible(true);
            unsafe = (Unsafe) f.get(null);  //如果为静态属性 则get 参数为null
            Field field = Main.class.getDeclaredField("a");
            valueOffset = unsafe.staticFieldOffset(field);
            System.out.println("offset：" + valueOffset);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws NoSuchFieldException {
        // cc
        {
            Main mm = new Main();
            Field field = Main.class.getDeclaredField("aa");
            long offset = unsafe.objectFieldOffset(field);
            System.out.println("aa offset：" + offset);
//            System.out.println("一个Main对象大小为："+ MySizeOf.sizeOf( mm ));
            System.out.println(ClassLayout.parseInstance(mm).toPrintable());
            System.out.println(GraphLayout.parseInstance(mm).totalSize());
        }
        // cc
        {
            Main mm = new Main();
            Field field = Main.class.getDeclaredField("cc");
            long offset = unsafe.objectFieldOffset(field);
            System.out.println("cc offset：" + offset);
        }
        // unsafe
        {
            Field field = Main.class.getDeclaredField("unsafe");
            long offset = unsafe.staticFieldOffset(field);
            System.out.println("unsafe offset：" + offset);
        }
        // dd
        {
            Main mm = new Main();
            Field field = Main.class.getDeclaredField("dd");
            long offset = unsafe.objectFieldOffset(field);
            System.out.println("dd offset：" + offset);
        }

    }

}
